home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993…stman Always Clicks Twice / ADC Developer CD (1993-01) (''The Postman Always Clicks Twice'')_iso / Dev.CD 199301.iso / Tools & Apps / Networking & Communications / Network Watch (DMZ) 1.0 / dMZMain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-17  |  35.8 KB  |  1,536 lines  |  [TEXT/KAHL]

  1. /*
  2. #-------------------------------------------------------------------------------------------
  3. #
  4. #    Program:    < DMZ 1.0 >
  5. #    File:        < dmzMain.c >
  6. #    
  7. #    by Pete Helme
  8. #    of <Apple Macintosh Developer Technical Support - or wheverever>
  9. #
  10. #    Copyright © 1990 Apple Computer, Inc.
  11. #    All rights reserved.
  12. #    
  13. #-------------------------------------------------------------------------------------------
  14. */
  15.  
  16. #ifndef THINK_C
  17. #include    <types.h>
  18. #include    <quickdraw.h>
  19. #include    <toolutils.h>
  20. #include    <fonts.h>
  21. #include    <events.h>
  22. #include    <windows.h>
  23. #include    <dialogs.h>
  24. #include    <menus.h>
  25. #include    <desk.h>
  26. #include    <textedit.h>
  27. #include    <scrap.h>
  28. #include    <segload.h>
  29. #include    <osevents.h>
  30. #include    <files.h>
  31. #include    <devices.h>
  32. #include    <memory.h>
  33. #include    <appletalk.h>
  34. #include    <lists.h>
  35. #include    <SysEqu.h>
  36. #include    <Script.h>
  37. #include    <CursorCtl.h>
  38. #include    <Resources.h>
  39. #else
  40. #endif
  41.  
  42. #include    "dmz.h"
  43.  
  44. #ifndef THINK_C
  45. extern _DataInit();
  46. #endif
  47.  
  48.  
  49. /*
  50.  *    imported Global Data objects, very expensive.
  51.  */
  52. extern char             gNameGlob[34];
  53. extern Boolean             gLookupFinished;
  54. extern Boolean             gUpdateListFlag;
  55. extern ListHandle         gZonesList, gObjectTypeList;
  56. extern myMPPParamBlock     *gPBLkUP;
  57.  
  58.  
  59. /*
  60.  *    Global Data objects, used by routines external to main().
  61.  */
  62.  
  63.  
  64. /* 
  65.  *    gDoneFlag, becomes true when File/Quit chosen.
  66.  */
  67. Boolean        gDoneFlag;            
  68.  
  69. /* 
  70.  *    gMyDialog, our main dialog.
  71.  */
  72. DialogPtr    gMyDialog;                /* main dialog */
  73.  
  74. /* 
  75.  *    gLookupDialog, where we can set our preference for lookup times and lookup strings for
  76.  *    matching.
  77.  */
  78. DialogPtr    gLookupDialog;            /* dialog for NBP lookup prefs */
  79.  
  80. /* 
  81.  *    gSortMode is our global sort value.
  82.  */
  83. long    gSortMode;
  84.  
  85. /* 
  86.  *    gSortItem is our global sort value for which dialog item should be selected.
  87.  */
  88. short    gSortItem = kObjectID;    /* default is the object sleector */
  89.  
  90. /* 
  91.  *    gContLookUp is used as a flag to keep track of the state of whether or not we are doing
  92.  *    continuous network lookups.
  93.  */
  94. Boolean    gContLookUp = true;
  95.  
  96. /* 
  97.  *    gMyEvent is used for external access (from the event loop) to the event record.
  98.  *    The main outside client of this guy is use in the list routines.
  99.  */
  100. EventRecord        gMyEvent;
  101.  
  102. /* 
  103.  *    GMAC is used to hold the result of a SysEnvirons call. This makes
  104.  *    it convenient for any routine to check the environment. (What?!? no use of _Gestalt!?!? "Shuddup.")
  105.  */
  106. SysEnvRec    GMAC;                /* set up by Initialize */
  107.  
  108. /* 
  109.  *    GHasWaitNextEvent is set at startup, and tells whether the WaitNextEvent
  110.  *    trap is available. If it is false, we know that we must call GetNextEvent. 
  111.  */
  112. Boolean        gHasWaitNextEvent;    /* set up by Initialize */
  113.  
  114. /* 
  115.  *     GInBackground is maintained by our osEvent handling routines. Any part of
  116.  *     the program can check it to find out if it is currently in the background. 
  117.  */
  118. Boolean        gInBackground;        /* maintained by Initialize and DoEvent */
  119.  
  120.  
  121. /* 
  122.  *     gATQEntry is used to install an AppleTalk Transition Queue Handler so that
  123.  *     the program can handle changes to AppleTalk status.
  124.  */
  125.  
  126. myATQEntry    gATQEntry;            /* set up by Initialize */
  127.  
  128.  
  129. /*
  130.  *    Prototypes
  131.  */
  132.  
  133. long ATalkTransQueue(long selector, myATQEntry *q, void *p);
  134.  
  135.  
  136.  
  137. /*
  138.  *    The Routines for dmzMain.
  139.  */
  140.  
  141.  
  142. #ifdef THINK_C2
  143. extern unsigned char * CrsrBusy : 0x8CD;
  144.  
  145. Ptr    gtheVBLPtr;
  146. Ptr    gtheTaskPtr;
  147.  
  148. void myVBLSpinInstall()
  149.     {
  150.     long        taskSize;
  151.     THz            curZone;
  152.     Handle        curses[4];
  153.     Ptr            taskAddress;
  154.         
  155.     /* load in the resources */
  156.     curses[1] = GetResource('CURS', 1001);
  157.     curses[2] = GetResource('CURS', 1002);
  158.     curses[3] = GetResource('CURS', 1003);
  159.     curses[4] = GetResource('CURS', 1004);
  160.         
  161.     asm {
  162.         bra     @theTaskEnd
  163.  
  164.     ; actual VBL Task
  165.     @theTaskBegin
  166.         movem.l    a0-a6/d0-d7, -(sp)        ; save 
  167.         bra.s    @1
  168.     @A5Storage
  169.         dc.l    0
  170.     @1
  171.         ; reset the vbl count
  172.         move.w     #5, OFFSET(VBLTask, vblCount)(a0)    
  173.         
  174.         ; restore A5 for globals we may have
  175.         lea        @A5Storage, a0
  176.         move.l    (a0), a5
  177.         bra.s    @45
  178.     @44    dc.w    #1001                ; storage for cursor type
  179.     @45    lea        @44, a0
  180.         add.w    #1, (a0)
  181.         move.w    (a0), d0
  182.         cmp.w    #1005, d0
  183.         blt        @10
  184.         
  185.         move.w    #1001, (a0)            ; start over with cursor type #1001
  186.         move.w    #1001, d0            ; it needs to be in d0
  187.         
  188.     @10    clr.l    -(a7)                ; make some space for return
  189.         move.w    d0, -(a7)            ; move in cursor type
  190.         _GetCursor
  191.         move.l    (a7)+, a0            ; move handle into a0
  192.         tst.b    CrsrBusy
  193.         bne.s    @vblExit
  194.         move.l    (a0), -(a7)            ; deref and push on stack
  195.         _SetCursor            
  196.     @vblExit
  197.         movem.l     (sp)+, a0-a6/d0-d7    ; restore 
  198.         rts
  199.     @theTaskEnd
  200.         
  201.         ; VBL initialization code
  202.         lea        @theTaskEnd, a0        ; address of tail of task
  203.         lea        @theTaskBegin, a1    ; head of task
  204.         move.l    a1, taskAddress        ; head of task address into pointer variable
  205.         move.l    a0, d0                ; get size of task
  206.         sub.l    a1, d0
  207.         move.l    d0, taskSize
  208.         
  209.         lea        @A5Storage, a0        ; put current A5 into our storage area in code
  210.         move.l    CurrentA5, (a0)
  211.         }        
  212.  
  213.     gtheVBLPtr = NewPtr(sizeof(VBLTask));
  214.     gtheTaskPtr = NewPtr(taskSize);
  215.  
  216.     /* move the task code into block in System heap */
  217.     BlockMove(taskAddress, gtheTaskPtr, taskSize);
  218.  
  219.     asm {
  220.         move.l     gtheTaskPtr, a1
  221.         move.l    gtheVBLPtr, a0
  222.         move.l    a1, OFFSET(VBLTask, vblAddr)(a0)        ; a1 contains address of moved TheTask
  223.         move.w     #vType, OFFSET(VBLTask, qType)(a0)
  224.         move.w     #10, OFFSET(VBLTask, vblCount)(a0)
  225.         move.w     #4, OFFSET(VBLTask, vblPhase)(a0)
  226.         _VInstall
  227.         }
  228. }
  229.  
  230. stopAndDisposeSpinCursor()
  231. {
  232.     VRemove(gtheVBLPtr);
  233.     DisposPtr(gtheVBLPtr);
  234.     DisposPtr(gtheTaskPtr);
  235. }
  236. #endif
  237.  
  238.  
  239. /*
  240.  *    Draws an outline around the particular item in the dialog.
  241.  */
  242. void DrawBoldItem(WindowPtr whichWindow, short theItem, short whichStrID)
  243. {
  244.     Rect         r;
  245.     short        kind;
  246.     Handle        h;
  247.     Str255        str;
  248.     FontInfo    info;
  249.     
  250.     GetFontInfo(&info);
  251.     GetDItem(whichWindow, theItem, &kind, &h, &r);
  252.     TextFace(bold);
  253.     MoveTo(r.left, r.top + info.ascent);
  254.     GetIndString(&str, kStringListID, whichStrID);
  255.     DrawString(str);
  256.     TextFace(0);
  257. }
  258.  
  259. /*
  260.  *    Main dialog handling routines for user item updating.  Here we'll update the 
  261.  *    two lists using _LUpdate and also draw a border around the list rectangles 
  262.  *    themselves.  We're actually drawing across the whole length of the content
  263.  *    region and not sure around the rView.  This is because the 6.x & older 
  264.  *    List Managers erase the region where the scoll bar use to be.  Since this
  265.  *    kinda bites we have to draw something to replace that whole.
  266.  *
  267.  *    Notice that the routine has to use Pascal calling conventions.
  268.  */
  269. pascal void updateUserItems(WindowPtr whichWindow, short theItem)
  270. {
  271.     GrafPtr     savedPort;
  272.     Rect         r;
  273.     
  274.     GetPort(&savedPort);
  275.     SetPort(whichWindow);
  276.  
  277.     switch(theItem) {
  278.         case kZoneListID:
  279.             LUpdate((*(**gZonesList).port).visRgn, gZonesList);
  280.             r = (**gZonesList).rView;
  281.             MoveTo(whichWindow->portRect.left, r.top-1);
  282.             LineTo(whichWindow->portRect.right, r.top-1);
  283.             MoveTo(whichWindow->portRect.left, r.bottom);
  284.             LineTo(whichWindow->portRect.right, r.bottom);
  285.             break;
  286.         case kNameTypeListID:
  287.             LUpdate((*(**gObjectTypeList).port).visRgn, gObjectTypeList);
  288.             r = (**gObjectTypeList).rView;
  289.             MoveTo(whichWindow->portRect.left, r.top-1);
  290.             LineTo(whichWindow->portRect.right, r.top-1);
  291.             MoveTo(whichWindow->portRect.left, r.bottom);
  292.             LineTo(whichWindow->portRect.right, r.bottom);
  293.             break;
  294.         case kZoneItemID:
  295.             DrawBoldItem(whichWindow, theItem, kZoneStrID);
  296.             break;
  297.         case kObjectID:
  298.             DrawBoldItem(whichWindow, theItem, kObjectStrID);
  299.             break;
  300.         case kTypeID:
  301.             DrawBoldItem(whichWindow, theItem, kTypeStrID);
  302.             break;
  303.         case kNetID:
  304.             DrawBoldItem(whichWindow, theItem, kNetStrID);
  305.             break;
  306.         case kNodeID:
  307.             DrawBoldItem(whichWindow, theItem, kNodeStrID);
  308.             break;
  309.         case kSocketID:
  310.             DrawBoldItem(whichWindow, theItem, kSktStrID);
  311.             break;
  312.         default:
  313.             break;
  314.         }
  315.     SetPort(savedPort);
  316. }
  317.     
  318. /* 
  319.  *    Generic routine for setting up dialog user items update procedure.  Saves us a 
  320.  *    few bytes by not duplicating the routine for each item.
  321.  */
  322. void getandSetIt(whichID)
  323.     short whichID;
  324. {
  325.     Rect     r;
  326.     short    kind;
  327.     Handle    h;
  328.     
  329.     GetDItem(gMyDialog, whichID, &kind, &h, &r);
  330.     SetDItem(gMyDialog, whichID, userItem, (Handle) updateUserItems, &r);
  331. }
  332.     
  333. /* 
  334.  *    For each userItem in the list, we'll call getandSetIt() to set up the 
  335.  *    update procedure pointer.  We'll also set up the port's font & size here.
  336.  */
  337. void setupUserItems()
  338. {
  339.     GrafPtr savedPort;
  340.     
  341.     GetPort(&savedPort);
  342.     SetPort(gMyDialog);
  343.     
  344.     TextFont(monaco);
  345.     TextSize(9);
  346.     
  347.     getandSetIt(kZoneListID);
  348.     getandSetIt(kNameTypeListID);
  349.     getandSetIt(kZoneItemID);
  350.     getandSetIt(kObjectID);
  351.     getandSetIt(kTypeID);
  352.     getandSetIt(kNetID);
  353.     getandSetIt(kNodeID);
  354.     getandSetIt(kSocketID);
  355.     
  356.     SetPort(savedPort);
  357. }
  358.  
  359. /* 
  360.  *    This sets the value of the lookup item control to on
  361.  */
  362. setupLookupItem()
  363. {
  364.     short        kind;
  365.     Handle        h;
  366.     Rect        r;
  367.  
  368.     GetDItem(gMyDialog, kDoLookupID, &kind, &h, &r);
  369.     SetCtlValue((ControlHandle)h, 1);
  370. }
  371.  
  372. /* 
  373.  *    This changes the current value of the gDoLookUp flag and reflects the state in the 
  374.  *    control
  375.  */
  376. doLookupItem()
  377. {
  378.     short        kind;
  379.     Handle        h;
  380.     Rect        r;
  381.  
  382.     GetDItem(gMyDialog, kDoLookupID, &kind, &h, &r);
  383.     
  384.     gContLookUp ^= 1; /* assigns bitwise XOR (changes from on to off and visa versa) */
  385.  
  386.     SetCtlValue((ControlHandle)h, (short)gContLookUp);
  387. }
  388.  
  389. /*
  390.  *     Set the default state of a large window for zooming 
  391.  */
  392. void setWindowStdState(WindowPtr theWindow)
  393. {
  394.     Rect        wRect;
  395.     Point        tlP, brP;
  396.     GrafPtr        savePort;
  397.     
  398.     GetPort(&savePort);
  399.     SetPort(theWindow);
  400.     
  401.     /* 
  402.      *    set the userState - convert coords to globals 
  403.      */
  404.     tlP.h = theWindow->portRect.left;
  405.     tlP.v = theWindow->portRect.top;
  406.     brP.h = theWindow->portRect.right;
  407.  
  408. #ifdef THINK_C
  409.     brP.v = screenBits.bounds.bottom-45;
  410. #else
  411.     brP.v = qd.screenBits.bounds.bottom-45;
  412. #endif
  413.  
  414.     LocalToGlobal(&tlP);
  415.     LocalToGlobal(&brP);
  416.     
  417.     wRect.left = tlP.h;
  418.     wRect.top = tlP.v;
  419.     wRect.right = brP.h;
  420.     wRect.bottom = brP.v;
  421.     
  422.     (**(WStateData **) (*(WindowPeek)theWindow).dataHandle).stdState = wRect;
  423.  
  424.     SetPort(savePort);
  425. }
  426.  
  427.  
  428. /*
  429.  *     Create our one and only dialog from the DLOG resource.
  430.  *     If the DLOG resource isn't there, go wash your socks.
  431.  */
  432. void setUpDialogs()
  433. {
  434.  
  435.     /*
  436.      *    make sure there is a 'dctb' resource present so color stuff works!
  437.      */
  438.     gMyDialog = GetNewDialog(kMainDialogID, nil, (WindowPtr) -1);
  439.     gLookupDialog = GetNewDialog(kLookupDialogID, nil, (WindowPtr) -1);
  440.  
  441.     setWindowStdState(gMyDialog);
  442.     
  443.     setupUserItems();
  444. }
  445.  
  446. /* 
  447.  *    This frames the Object, type, etc. items in the main dialog window.  This tells the 
  448.  *    user which item the list is currently sorting on. The box size is based on the
  449.  *    size of the text itself and not on the dialog item rectangle size.  On a machine which
  450.  *    supports color, we'll use RGB value form HiliteRGB for the outline box color. No need
  451.  *    for this utlity to use stodgy old black and white if it doesn' t have too.. And it 
  452.  *    also adds some uniformity to the selection idea since the lists also use HiliteRGB.
  453.  *    One thing we do not do with the selection is remove it if window is in background...
  454.  *    ...should we to be truley HIG compatible?
  455.  */
  456. void FrameItem(whichDialog, whichItem)
  457.     DialogPtr     whichDialog;
  458.     short         whichItem;
  459. {
  460.     short        kind;
  461.     Handle        h;
  462.     Rect        r;
  463.     PenState    ps;
  464.     RGBColor    rgb, curRGB;
  465.     char        str[10];
  466.     FontInfo    info;
  467.     short        strListID;
  468.     GrafPtr        savePort;
  469.     
  470.     GetPort(&savePort);
  471.     SetPort(whichDialog);
  472.     
  473.     TextFace(bold);
  474.  
  475.     /* 
  476.      *    unframe old item 
  477.      */
  478.     GetDItem(whichDialog, gSortItem, &kind, &h, &r);
  479.     
  480.     switch (gSortItem) {
  481.         case kObjectID:
  482.             strListID = kObjectStrID;
  483.             break;
  484.         case kTypeID:
  485.             strListID = kTypeStrID;
  486.             break;
  487.         case kNetID:
  488.             strListID = kNetStrID;
  489.             break;
  490.         case kNodeID:
  491.             strListID = kNodeStrID;
  492.             break;
  493.         case kSocketID:
  494.             strListID = kSktStrID;
  495.             break;
  496.         }
  497.         
  498.     GetIndString(&str, kStringListID, strListID);
  499.     GetPenState(&ps);
  500.  
  501. #ifdef THINK_C
  502.     PenPat(white);
  503. #else
  504.     PenPat(qd.white);
  505. #endif
  506.  
  507.     GetFontInfo(&info);
  508.     r.right = r.left + StringWidth(str) + 2;
  509.     r.left -= 2;
  510.     r.bottom = r.top;
  511.     r.bottom += info.ascent + info.descent + 2;    
  512.     r.top -= 1;
  513.     FrameRect(&r);
  514.     SetPenState(&ps);
  515.  
  516.     /* 
  517.      *    If Color QD is present, we will change the foreground color to HiliteRGB
  518.      *    so that our "selection" frame will match our list's hilites.
  519.      */
  520.     if(GMAC.hasColorQD) {
  521.         BlockMove((Ptr) HiliteRGB,(Ptr)  &rgb, sizeof(RGBColor));
  522.         GetForeColor(&curRGB);
  523.         RGBForeColor(&rgb);
  524.     }
  525.  
  526.     /* 
  527.      *    frame new item 
  528.      */
  529.     switch (whichItem) {
  530.         case kObjectID:
  531.             strListID = kObjectStrID;
  532.             break;
  533.         case kTypeID:
  534.             strListID = kTypeStrID;
  535.             break;
  536.         case kNetID:
  537.             strListID = kNetStrID;
  538.             break;
  539.         case kNodeID:
  540.             strListID = kNodeStrID;
  541.             break;
  542.         case kSocketID:
  543.             strListID = kSktStrID;
  544.             break;
  545.         }
  546.         
  547.     GetDItem(whichDialog, whichItem, &kind, &h, &r);
  548.     GetIndString(&str, kStringListID, strListID);
  549.  
  550.     GetFontInfo(&info);
  551.     r.right = r.left + StringWidth(str) + 2;
  552.     r.left -= 2;
  553.     r.bottom = r.top;
  554.     r.bottom += info.ascent + info.descent + 2;    
  555.     r.top -= 1;
  556.     FrameRect(&r);
  557.     
  558.     TextFace(0);
  559.  
  560.     /* 
  561.      *    Reset foreground color.
  562.      */
  563.     if(GMAC.hasColorQD)
  564.         RGBForeColor(&curRGB);
  565.     
  566.     gSortItem = whichItem;
  567.  
  568.     SetPort(savePort);
  569. }
  570.  
  571. /* 
  572.  *    This is the routine called by _DialogSelect.  It handles all userItem events
  573.  *    except updating.
  574.  */
  575. void doModeless(whichDialog, whichItem)
  576.     DialogPtr whichDialog;
  577.     short whichItem;
  578. {        
  579.     if(whichDialog == gMyDialog) {
  580.         switch(whichItem) {
  581.             case kZoneListID: /* 1 */
  582.                 doZonesListStuff();
  583.                 break;
  584.             case kNameTypeListID: /* 2 */
  585.                  doObjectTypeListStuff();
  586.                  break;
  587.             case kObjectID:
  588.                 gSortMode = sortOnObject;
  589.                 FrameItem(whichDialog, whichItem);
  590.                 getTypesNamesInZone(&gNameGlob);
  591.                 break;
  592.             case kTypeID:
  593.                 gSortMode = sortOnType;
  594.                 FrameItem(whichDialog, whichItem);
  595.                 getTypesNamesInZone(&gNameGlob);
  596.                 break;
  597.             case kNetID:
  598.                 gSortMode = sortOnNet;
  599.                 FrameItem(whichDialog, whichItem);
  600.                 getTypesNamesInZone(&gNameGlob);
  601.                 break;
  602.             case kNodeID:
  603.                 gSortMode = sortOnNode;
  604.                 FrameItem(whichDialog, whichItem);
  605.                 getTypesNamesInZone(&gNameGlob);
  606.                 break;
  607.             case kSocketID:    
  608.                 gSortMode = sortOnSocket;
  609.                 FrameItem(whichDialog, whichItem);
  610.                 getTypesNamesInZone(&gNameGlob);
  611.                 break;
  612.             default:
  613.                 break;
  614.             }
  615.     }
  616. }
  617.         
  618. /*    
  619.  *    doIdle()  Called repeatedly in main event loop for cursor tasks
  620.  *    and NBPLookups.
  621.  */
  622. void doIdle()     
  623. {
  624.     if(gUpdateListFlag == true) {
  625.         processListUpdate();
  626.     }
  627. }
  628.  
  629. /* 
  630.  *    draws the grow box 
  631.  */ 
  632. DrawGrowBox(WindowPtr theWindow)
  633. {
  634.     Rect        r, windowRect;
  635.     GrafPtr        tempPort;
  636.     
  637.     /*
  638.      *    copy theWindow->portRect into a local rect for efficency.  
  639.      *    no need to dereference theWindow all the time.
  640.      */
  641.     GetPort(&tempPort);
  642.     SetPort(theWindow);
  643.     
  644.     windowRect = theWindow->portRect;
  645.     
  646.     if(((WindowPeek)theWindow)->hilited) {
  647.         MoveTo(windowRect.right-12, windowRect.bottom-12);
  648.         LineTo(windowRect.right-6, windowRect.bottom-12);
  649.         LineTo(windowRect.right-6, windowRect.bottom-6);
  650.         LineTo(windowRect.right-12, windowRect.bottom-6);
  651.         LineTo(windowRect.right-12, windowRect.bottom-12);
  652.     
  653.         MoveTo(windowRect.right-5, windowRect.bottom-10);
  654.         LineTo(windowRect.right-2, windowRect.bottom-10);
  655.         LineTo(windowRect.right-2, windowRect.bottom-2);
  656.         LineTo(windowRect.right-10, windowRect.bottom-2);
  657.         LineTo(windowRect.right-10, windowRect.bottom-5);
  658.         }
  659.     else {
  660.         SetRect(&r, windowRect.right-17, windowRect.bottom-15,
  661.             windowRect.right, windowRect.bottom);
  662.         EraseRect(&r);
  663.         }
  664.  
  665.     MoveTo(windowRect.right-15, windowRect.bottom);
  666.     LineTo(windowRect.right-15, windowRect.bottom-15);
  667.     MoveTo(windowRect.right-15, windowRect.bottom-15);
  668.     LineTo(windowRect.right, windowRect.bottom-15);
  669.  
  670.     SetPort(tempPort);
  671. }
  672.  
  673. /* 
  674.  *    updates the gSortItem rectangle 
  675.  */
  676. void doUpdate(WindowPtr theWindow)
  677. {
  678.     RGBColor    rgb, curRGB;
  679.     
  680.     if(theWindow == gMyDialog) {
  681.         if(GMAC.hasColorQD) {
  682.             BlockMove((Ptr) HiliteRGB, (Ptr) &rgb, sizeof(RGBColor));
  683.             GetForeColor(&curRGB);
  684.             RGBForeColor(&rgb);
  685.             }
  686.     
  687.         FrameItem(gMyDialog, gSortItem);
  688.     
  689.         if(GMAC.hasColorQD)
  690.             RGBForeColor(&curRGB);
  691.  
  692.         DrawGrowBox(theWindow);
  693.         }
  694. }
  695.  
  696.  
  697. /*    
  698.  *    ShowMainWindowAndSizeIt() opens our main window to the size of our main screen
  699.  *    and displays it.
  700.  */
  701. ShowMainWindowAndSizeIt()
  702. {
  703.     extern void DoZoomWindow(WindowPtr whichWindow, short partCode);
  704.     
  705.     /*
  706.      *    show it…
  707.      */
  708.     ShowWindow(gMyDialog);
  709.     
  710.     /*
  711.      *    and resize it.
  712.      */
  713.     /* DoZoomWindow(gMyDialog, inZoomOut); */
  714. }
  715.  
  716.  
  717. /*    
  718.  *    doInitializing() Called at application boot to allocate master pointers,
  719.  *    check SysEnvirons() for Mac type, check for WaitNextEvent implementation.
  720.  *    and call all other initializing routines.
  721.  */
  722. void doInitializing()
  723. {
  724.     extern        void setupMenus();
  725.     OSErr        ignoreError, err;
  726.     CursHandle    theWatch;
  727.     short        count;
  728.     
  729.     /*
  730.      * Initialization traps
  731.      */
  732.     MaxApplZone();
  733.  
  734.     MoreMasters();
  735.     MoreMasters();
  736.     MoreMasters();
  737.     MoreMasters();
  738.     
  739.     /* 
  740.      *    ignore the error returned from SysEnvirons; even if an error occurred,
  741.      *    the SysEnvirons glue will fill in the SysEnvRec 
  742.      */
  743.     ignoreError = SysEnvirons(sysEnvironsVersion, &GMAC);
  744.     if ( GMAC.machineType < 0 )                 /*old machines have...*/ 
  745.         gHasWaitNextEvent = false;             /*no separate trap table; no WaitNextEvent */
  746.     else
  747.         gHasWaitNextEvent = (GetTrapAddress(0x60)!=GetTrapAddress(0x9F));
  748.  
  749.     gInBackground = false;
  750.  
  751. #ifdef THINK_C
  752.     InitGraf(&thePort);
  753. #else
  754.     InitGraf(&qd.thePort);
  755. #endif
  756.     
  757.     InitFonts();
  758.     FlushEvents(everyEvent, 0);
  759.     InitWindows();
  760.     InitMenus();
  761.     InitDialogs(0L);    
  762.  
  763.     /*    
  764.      *    This next bit of code is necessary to allow the default button of our
  765.      *    alert be outlined.
  766.      *    Changed to call _EventAvail so that we don't lose some important
  767.      *    events. 
  768.      */     
  769.     for (count = 1; count <= 3; count++) {
  770.         EventAvail(everyEvent, &gMyEvent);
  771.     }
  772.  
  773.     /* 
  774.      *    make 'em wait 
  775.      */
  776.     theWatch = GetCursor(watchCursor);    
  777.     SetCursor(*theWatch);
  778.  
  779.     /* 
  780.      *    setupmenus 
  781.      */
  782.     setupMenus();            
  783.  
  784.     /*
  785.      * setup the dialog.
  786.      */
  787.     setUpDialogs();
  788.     SetPort(gMyDialog);
  789.     
  790.     /*
  791.      * setup the list stuff.
  792.      */
  793.     OpenZonesList();
  794.     OpenObjectTypeList();
  795.  
  796.     /*
  797.      * initialize assorted and sundry variables
  798.      */
  799.     gDoneFlag = false;
  800.     gNameGlob[0] = 0;
  801.     gUpdateListFlag = false;
  802.     gLookupFinished = true;
  803.     gSortMode = sortOnObject;
  804.     
  805.     /*
  806.      * install our tranisiton queue handler
  807.      */
  808.     if (GMAC.atDrvrVersNum >= 53) {
  809.         gATQEntry.CallAddr = (Ptr)&ATalkTransQueue;
  810.         err = LAPAddATQ((ATQEntryPtr)&gATQEntry);
  811.         if (err != noErr)
  812.             ExitToShell();
  813.     }
  814.     
  815.     
  816.     /*
  817.      * setup the appletalk stuff.
  818.      */
  819.     InitAppleTalkVars();
  820.  
  821.     /*
  822.      * open the main window & size it to the main screen.
  823.      */
  824.     ShowMainWindowAndSizeIt();
  825.         
  826.     InitCursor();
  827. }
  828.     
  829. /*
  830.  *    uses predefined value to calculate 'grid height' of list.
  831.  */
  832. short resizeRectToListCellSize(short height)
  833. {
  834.     short    temp;
  835.  
  836.     height -= 113;
  837.     temp = height % 11;
  838.     height += (113 - temp);
  839.  
  840.     return height;
  841. }
  842.  
  843. void resizeWindow(WindowPtr whichWindow, short height)
  844. {
  845.     short        kind;
  846.     Handle        h;
  847.     Rect            r;
  848.     RgnHandle    savedClipRgn, theListMgrSucksRgn;
  849.  
  850.     /*
  851.      *    this 'grids' the bottom of the window to the right height to fit the list cell size
  852.      */
  853.     SizeWindow(whichWindow, whichWindow->portRect.right-whichWindow->portRect.left, height, true);
  854.  
  855.     GetDItem(gMyDialog, kNameTypeListID, &kind, &h, &r);
  856.     
  857.     savedClipRgn = NewRgn();
  858.     theListMgrSucksRgn = NewRgn();
  859.     GetClip(savedClipRgn);
  860.     SetClip(theListMgrSucksRgn);
  861.     
  862.     r.bottom = whichWindow->portRect.bottom;
  863.     SetDItem(gMyDialog, kNameTypeListID, kind, h, &r);
  864.     
  865.     LSize((**gObjectTypeList).rView.right-(**gObjectTypeList).rView.left, (whichWindow->portRect.bottom)-(**gObjectTypeList).rView.top, gObjectTypeList);
  866.  
  867.     SizeControl((**gObjectTypeList).vScroll, (**(**gObjectTypeList).vScroll).contrlRect.right - 
  868.         (**(**gObjectTypeList).vScroll).contrlRect.left, (**(**gObjectTypeList).vScroll).contrlRect.bottom - 
  869.         (**(**gObjectTypeList).vScroll).contrlRect.top - 15);
  870.  
  871.     SetClip(savedClipRgn);
  872.     DisposeRgn(savedClipRgn);
  873.     DisposeRgn(theListMgrSucksRgn);
  874.  
  875.     /*
  876.      *    Erase grow box icon
  877.      */
  878.     SetRect(&r, whichWindow->portRect.right-14, whichWindow->portRect.bottom-15, 
  879.         whichWindow->portRect.right, whichWindow->portRect.bottom);
  880.     EraseRect(&r);
  881. }
  882.  
  883. /*    
  884.  *    Check to see if a window belongs to the application. If the window pointer
  885.  *    passed was NIL, then it could not be an application window. WindowKinds
  886.  *    that are negative belong to the system and windowKinds less than userKind
  887.  *    are reserved by Apple except for windowKinds equal to dialogKind, which
  888.  *    mean it is a dialog.
  889.  *    1.02 - In order to reduce the chance of accidentally treating some window
  890.  *    as an AppWindow that shouldn't be, we'll only return true if the windowkind
  891.  *    is userKind. If you add different kinds of windows to Sample you'll need
  892.  *    to change how this all works. 
  893.  */
  894.  
  895. Boolean IsAppWindow(window)
  896.     WindowPtr    window;
  897. {
  898.     short        windowKind;
  899.  
  900.     if ( window == nil )
  901.         return false;
  902.     else {    /* application windows have windowKinds = userKind (8) */
  903.         windowKind = ((WindowPeek) window)->windowKind;
  904.         return (windowKind == userKind);
  905.     }
  906. } /*IsAppWindow*/
  907.  
  908.  
  909. /* Check to see if a window belongs to a desk accessory. */
  910.  
  911. Boolean IsDAWindow(window)
  912.     WindowPtr    window;
  913. {
  914.     if ( window == nil )
  915.         return false;
  916.     else    /* DA windows have negative windowKinds */
  917.         return ((WindowPeek) window)->windowKind < 0;
  918. } /*IsDAWindow*/
  919.  
  920.  
  921. /* Close a window. This handles desk accessory and application windows. */
  922.  
  923. /*    
  924.  *    1.01 - At this point, if there was a document associated with a
  925.  *    window, you could do any document saving processing if it is 'dirty'.
  926.  *    DoCloseWindow would return true if the window actually closed, i.e.,
  927.  *    the user didn’t cancel from a save dialog. This result is handy when
  928.  *    the user quits an application, but then cancels the save of a document
  929.  *    associated with a window. 
  930.  */
  931.  
  932. Boolean DoCloseWindow(window)
  933.     WindowPtr    window;
  934. {
  935.     if ( IsDAWindow(window) )
  936.         CloseDeskAcc(((WindowPeek) window)->windowKind);
  937.     else if ( window == gLookupDialog ) {
  938.         HideWindow(window);
  939.     }
  940.     return true;
  941. } /*DoCloseWindow*/
  942.  
  943.  
  944. /*
  945.  *    The USER, let's call him "Bob", has clicked in the zoom box so now he, "Bob", probably expects
  946.  *    us to do something about it.
  947.  */
  948.  
  949. void DoZoomWindow(WindowPtr whichWindow, short partCode)
  950. {
  951.     WindowPeek        wp;
  952.     WStateData        **wStateH;
  953.     Rect            globalPortRect, theSect, zoomRect;
  954.     GDHandle        nthDevice, dominantGDevice;
  955.     long            sectArea, greatestArea;
  956.     short            bias;
  957.     Boolean            sectFlag;
  958.     short            windowHeight, windowWidth;
  959.     
  960.     wp = (WindowPeek) whichWindow;
  961.  
  962.     SetPort(whichWindow);
  963.     EraseRect(&whichWindow->portRect);
  964.     
  965.     wStateH = (WStateData **)wp->dataHandle;
  966.  
  967.     if(partCode == inZoomOut) {
  968.         if(GMAC.hasColorQD) {
  969.             /* 
  970.                *    Get the width of our window for later use. 
  971.                */
  972.             windowWidth = whichWindow->portRect.right - whichWindow->portRect.left;
  973.  
  974.             /* 
  975.                *    window's portRect must be converted to global coordinates... a pain in C...
  976.                */
  977.             globalPortRect = (**(*(WindowPeek)whichWindow).strucRgn).rgnBBox; /*whichWindow->portRect;*/
  978.             
  979.             /*
  980.             pt.h = globalPortRect.left;
  981.             pt.v = globalPortRect.top;
  982.             LocalToGlobal(&pt);
  983.             globalPortRect.left = pt.h;
  984.             globalPortRect.top = pt.v;
  985.     
  986.             pt.h = globalPortRect.right;
  987.             pt.v = globalPortRect.bottom;
  988.             LocalToGlobal(&pt);
  989.             globalPortRect.right = pt.h;
  990.             globalPortRect.bottom = pt.v;
  991.             */
  992.  
  993.             /*
  994.              *    Now let's calculate the height of the window's title bar 
  995.              */
  996.             bias = (**(*(WindowPeek)whichWindow).contRgn).rgnBBox.top -
  997.                 (**(*(WindowPeek)whichWindow).strucRgn).rgnBBox.top - 1; 
  998.             
  999.             nthDevice = GetDeviceList();
  1000.  
  1001.             /*
  1002.              *    This loop checks the window against all the gdRects in the   
  1003.              *    gDevice list and remembers which gdRect contains the largest 
  1004.              *    portion of the window being zoomed. 
  1005.              */
  1006.             greatestArea = 0;
  1007.             while(nthDevice != 0L) {
  1008.                 sectFlag = SectRect(&globalPortRect, &(**nthDevice).gdRect, &theSect);
  1009.                 sectArea = (long)(theSect.right - theSect.left) * (theSect.bottom - theSect.top);
  1010.                 if(sectArea > greatestArea) {
  1011.                     greatestArea = sectArea;
  1012.                     dominantGDevice = nthDevice;
  1013.                     }
  1014.                 nthDevice = GetNextDevice(nthDevice);
  1015.                 } 
  1016.             
  1017.             /*
  1018.              *    We must create a zoom rectangle manually in this case. 
  1019.              *    account for menu bar height as well, if on main device 
  1020.              */
  1021.             if (dominantGDevice == GetMainDevice()) 
  1022.                 bias = bias + GetMBarHeight();
  1023.               
  1024.             /*
  1025.              *    Now let's set our newly discovered 'zoom' rectangle. 3 is the recommend inset
  1026.              *    value from the device's boundries.
  1027.              */
  1028.             SetRect(&zoomRect,(**dominantGDevice).gdRect.left+3,(**dominantGDevice).gdRect.top+bias+3,
  1029.                 (**dominantGDevice).gdRect.right-3,(**dominantGDevice).gdRect.bottom-3);
  1030.               
  1031.             /*
  1032.              *    Set up the WStateData record for this window. 
  1033.              */
  1034.             (**wStateH).stdState = zoomRect;
  1035.             windowHeight = zoomRect.bottom-zoomRect.top;
  1036.  
  1037.             /*
  1038.              *    Resize the bottom coordinate based on the size of a cell for neatness. 
  1039.              */
  1040.             (**wStateH).stdState.bottom = zoomRect.top + resizeRectToListCellSize(windowHeight);
  1041.             
  1042.             /*
  1043.              *    We have a fixed width for our window.  Reset it now. 
  1044.              */
  1045.             (**wStateH).stdState.right = (**wStateH).stdState.left + windowWidth;
  1046.             }
  1047.         else {
  1048.             /*
  1049.              *    We (probably) only have one device so this is all we need to do. 
  1050.              */
  1051. #ifdef THINK_C
  1052.             windowHeight = screenBits.bounds.bottom-7-(**wStateH).stdState.top;
  1053. #else
  1054.             windowHeight = qd.screenBits.bounds.bottom-7-(**wStateH).stdState.top;
  1055. #endif
  1056.             (**wStateH).stdState.bottom = (**wStateH).stdState.top + resizeRectToListCellSize(windowHeight);
  1057.             }
  1058.         }
  1059.         
  1060.     ZoomWindow(whichWindow, partCode, true);
  1061.     resizeWindow(whichWindow, (short) (whichWindow->portRect.bottom-whichWindow->portRect.top));
  1062. }
  1063.  
  1064. void DoGrowWindow(WindowPtr whichWindow, EventRecord    *evt)
  1065. {
  1066.     Rect        limitRect;
  1067.     long        newSize;
  1068.     GrafPtr        savePort;
  1069.     short        height;
  1070.     
  1071.     GetPort(&savePort);
  1072.     
  1073. #ifdef THINK_C
  1074.     limitRect = screenBits.bounds;
  1075. #else
  1076.     limitRect = qd.screenBits.bounds;
  1077. #endif
  1078.  
  1079.     SetPort(whichWindow);
  1080.  
  1081.     limitRect.right = whichWindow->portRect.right + 1;
  1082.     limitRect.left = whichWindow->portRect.right + 1;
  1083.     limitRect.top = whichWindow->portRect.top + 203;
  1084.     
  1085.     newSize = GrowWindow(whichWindow, evt->where, &limitRect);
  1086.  
  1087.     if(newSize != 0L) {
  1088.         /* 
  1089.          *    set to our dialog, erase the content region and re-size the window
  1090.          */
  1091.         /* SizeWindow(whichWindow, LoWord(newSize), height, true);*/
  1092.         height = HiWord(newSize);
  1093.         height = resizeRectToListCellSize(height);
  1094.         resizeWindow(whichWindow, height);
  1095.         }
  1096.  
  1097.     SetPort(savePort);
  1098. }
  1099.  
  1100. void main()
  1101. {
  1102.     WindowPtr            whichWindow;
  1103.     DialogPtr            whichDialog;
  1104.     short                 whichItem;
  1105.     extern     void         doCommand();
  1106.     extern  void         doCleanUpAndTerminate();
  1107.     extern     void         doActivate();
  1108.     extern  void         doDeactivate();
  1109.     Boolean                processIt;
  1110.     short                partCode;
  1111.     EventRecord            myEvent;
  1112.         
  1113.     doInitializing();
  1114.     
  1115.     for ( ;; ) {
  1116.         if (gDoneFlag) 
  1117.             break;        /* from main event loop */
  1118.             
  1119.         if ( gHasWaitNextEvent ) 
  1120.             /* 
  1121.              *    no sleeping for us... 
  1122.              */
  1123.             processIt = WaitNextEvent(everyEvent, &myEvent, 0L, 0L);
  1124.         else {
  1125.             SystemTask();
  1126.             processIt = GetNextEvent(everyEvent, &myEvent);
  1127.             }
  1128.  
  1129.         /* 
  1130.          *    this checks to make sure we don't pass any cmd key events to the 
  1131.          *    modeless dialog.  This must be called even if the event traps
  1132.          *    return false for text edit idling.
  1133.          */
  1134.         /*
  1135.         if(!((myEvent.what==keyDown)&&(gMyEvent.modifiers & cmdKey))) {
  1136.             if (!((gMyEvent.what==keyDown)&&((char)(gMyEvent.message & charCodeMask))>'9')
  1137.             &&!((gMyEvent.what==keyDown)&&((char)(gMyEvent.message & charCodeMask))<(char)8)) {
  1138.                 if(IsDialogEvent(&gMyEvent)) {
  1139.                     if(DialogSelect(&gMyEvent, &whichDialog, &whichItem))
  1140.                         doModeless(whichDialog, whichItem);
  1141.                 }
  1142.             }
  1143.         }
  1144.         */
  1145.         
  1146.         if(!(myEvent.modifiers & cmdKey)) {
  1147.             if(IsDialogEvent(&myEvent)) {
  1148.                 if(DialogSelect(&myEvent, &whichDialog, &whichItem))
  1149.                     doModeless(whichDialog, whichItem);
  1150.             }
  1151.         }
  1152.         gMyEvent = myEvent;
  1153.         
  1154.         /*
  1155.         if(IsDialogEvent(&myEvent)) {
  1156.             if(DialogSelect(&myEvent, &whichDialog, &whichItem)) {
  1157.                 if(whichDialog == gMyDialog)
  1158.                     doModeless(whichDialog, whichItem);    
  1159.                 }
  1160.         }
  1161.         */
  1162.         
  1163.          {    
  1164.             switch (myEvent.what) 
  1165.                 {    
  1166.                 case nullEvent:
  1167.                     doIdle();
  1168.                     break;
  1169.                                 
  1170.                 case mouseDown:
  1171.                     partCode = FindWindow(myEvent.where, &whichWindow);
  1172.                     switch (partCode) 
  1173.                         {
  1174.                         case inSysWindow:
  1175.                             SystemClick(&myEvent, whichWindow);
  1176.                             break;
  1177.     
  1178.                         case inMenuBar:
  1179.                             doCommand(MenuSelect(myEvent.where));
  1180.                             break;
  1181.     
  1182.                         case inDrag:
  1183.                             #ifdef THINK_C
  1184.                                 DragWindow(whichWindow, myEvent.where, &screenBits.bounds);
  1185.                             #else
  1186.                                 DragWindow(whichWindow, myEvent.where, &qd.screenBits.bounds);
  1187.                             #endif
  1188.                             break;
  1189.     
  1190.                         case inGoAway:
  1191.                             if (TrackGoAway(whichWindow, myEvent.where))
  1192.                                 DoCloseWindow(whichWindow);             /* we don’t care if the user cancelled */
  1193.                             break;
  1194.     
  1195.                         case inGrow:
  1196.                             DoGrowWindow(whichWindow, &myEvent);
  1197.                             break;
  1198.     
  1199.                         case inContent:
  1200.                             if(whichWindow != FrontWindow())
  1201.                                 SelectWindow(whichWindow);
  1202.                             break;
  1203.     
  1204.                         case inZoomIn:
  1205.                         case inZoomOut:
  1206.                             if(whichWindow == FrontWindow()) {
  1207.                                 if(TrackBox(whichWindow, myEvent.where, partCode)) 
  1208.                                     DoZoomWindow(whichWindow, partCode);
  1209.                                 }
  1210.                             break;
  1211.     
  1212.                         default:
  1213.                             break;
  1214.                         }
  1215.                     break;
  1216.     
  1217.                 case keyDown:
  1218.                 case autoKey:
  1219.                     if (gMyDialog == FrontWindow()) {
  1220.                         if (myEvent.modifiers & cmdKey) 
  1221.                             doCommand(MenuKey(myEvent.message & charCodeMask));
  1222.                         else if ((myEvent.message & charCodeMask) == kEnterKey
  1223.                             || (myEvent.message & charCodeMask) == kReturnKey)
  1224.                             doObjectDoubleClick();
  1225.                         }
  1226.                     else if (gLookupDialog == FrontWindow())
  1227.                         if (myEvent.modifiers & cmdKey) 
  1228.                             doCommand(MenuKey(myEvent.message & charCodeMask));
  1229.                     break;
  1230.     
  1231.                 case activateEvt:
  1232.                     if ((WindowPtr) myEvent.message == gMyDialog || (WindowPtr) myEvent.message == gLookupDialog) {
  1233.                         if (myEvent.modifiers & activeFlag) {
  1234.                             if ((WindowPtr) myEvent.message == gMyDialog)
  1235.                                 doActivate(gMyDialog);                        
  1236.                             DisableItem(GetMHandle(editID), 0);
  1237.                         } 
  1238.                         else {
  1239.                             if ((WindowPtr) myEvent.message == gMyDialog)
  1240.                                 doDeactivate(gMyDialog);                        
  1241.                             if(FrontWindow() != gMyDialog && FrontWindow() != gLookupDialog)
  1242.                                 EnableItem(GetMHandle(editID), 0);
  1243.                         }
  1244.                     }
  1245.                     DrawMenuBar();
  1246.                     break;
  1247.     
  1248.                 case updateEvt:
  1249.                     /* 
  1250.                      *    all our updating is handled by the Dialog Mananger
  1251.                      *     and our userItem update routines.
  1252.                      */
  1253.                      doUpdate((WindowPtr) myEvent.message);
  1254.                      break;
  1255.     
  1256.                 case osEvent:
  1257.                     switch (myEvent.message >> 24) {     /* high byte of message */
  1258.                         case mouseMovedMessage:
  1259.                             doIdle();    /* mouse moved is also an idle event */
  1260.                             break;
  1261.                         case suspendResumeMessage:
  1262.                             if ( myEvent.message & resumeMask ) {
  1263.                                 /* 
  1264.                                  *    resume event received
  1265.                                  */
  1266.                                 doActivate(gMyDialog);
  1267.                                 gInBackground = false;
  1268.                             } else {
  1269.                                 /* 
  1270.                                  *    suspend event received
  1271.                                  */
  1272.                                 doDeactivate(gMyDialog);
  1273.                                 gInBackground = true;
  1274.                                 }
  1275.                             DrawMenuBar();
  1276.                             break;
  1277.                         }
  1278.                     break;
  1279.                 }/*endsw myEvent.what*/
  1280.             }
  1281.         }
  1282.  
  1283.     doCleanUpAndTerminate();
  1284. }
  1285.  
  1286. /*
  1287.  *     Handle any activate routines here.  In our case this mean activating the lists and redrawing
  1288.  *    our grow box.
  1289.  */
  1290. void doActivate(WindowPtr theWindow)
  1291. {
  1292.     /* 
  1293.      *    Hilites scroll bars and updates scrollbar control max fields with _LActivate(true, ...).
  1294.      */
  1295.     LActivate(true, gZonesList);
  1296.     LActivate(true, gObjectTypeList);
  1297.  
  1298.     /*     
  1299.      *    this is like really dumb but necessary for ListManager
  1300.      *    skankiness.  It forces the lists's scroll bar's to
  1301.      *    recalculate & update which is not handled by _LActivate.
  1302.  
  1303.     LUpdate((*(**gZonesList).port).visRgn, gZonesList);
  1304.     LUpdate((*(**gObjectTypeList).port).visRgn, gObjectTypeList);
  1305.     */
  1306.  
  1307.     DrawGrowBox(theWindow);
  1308. }
  1309.     
  1310. /*
  1311.  * 
  1312.  */
  1313. void doDeactivate(WindowPtr    theWindow)
  1314. {
  1315.     /* 
  1316.      *    instead of only calling _LActivate(false, ...), we're going to unhilite 
  1317.      *    the two scroll bars too.  _LActivate(false, ...) actually hides the WHOLE 
  1318.      *    scroll bar control, outline and all, which isn't really to Human Interface 
  1319.      *    Guidelines or Pete's Mom's Prairie Home Programming Rules.  Besides it 
  1320.      *    looks really silly.
  1321.      *
  1322.      *  If you want to use the LActivate instead substitute the following lines
  1323.      *    for the HilitControl and the LActivate flag lines.
  1324.      *    2/17/90 pvh - forget it.  just use the LActivate call instead.  toolbox wins.
  1325.      */
  1326.     
  1327.     LActivate(false, gZonesList);
  1328.     LActivate(false, gObjectTypeList);
  1329.     
  1330.     /*
  1331.     (**gZonesList).lActive = false;
  1332.     (**gObjectTypeList).lActive = false;
  1333.     HiliteControl((**gZonesList).vScroll, 255);
  1334.     HiliteControl((**gObjectTypeList).vScroll, 255);
  1335.     ShowControl((**gZonesList).vScroll);
  1336.     ShowControl((**gObjectTypeList).vScroll);
  1337.     */
  1338.  
  1339.     DrawGrowBox(theWindow);
  1340. }
  1341.     
  1342. /*
  1343.  * Cleanup here.  Calls all clean up routines.
  1344.  */
  1345. void doCleanUpAndTerminate()
  1346. {
  1347.     closeUpOurAppleTalk();
  1348.     HideWindow(gMyDialog);
  1349.     DisposOfMyLists();
  1350.     DisposDialog(gMyDialog);
  1351.     LAPRmvATQ((ATQEntryPtr)&gATQEntry);
  1352.     
  1353.     ExitToShell();
  1354. }
  1355.     
  1356. /*
  1357.  * Set up the Apple, File, and Edit menus using the MBAR resource.
  1358.  * If the MENU resources are missing, we die and find something better to do.
  1359.  */
  1360. void setupMenus()
  1361. {
  1362.     Handle        myMenuBar;
  1363.     
  1364.     myMenuBar = GetNewMBar(128);
  1365.     SetMenuBar(myMenuBar);
  1366.     DisposHandle(myMenuBar);
  1367.     AddResMenu(GetMHandle(appleID), 'DRVR');
  1368.     
  1369.     DrawMenuBar();
  1370. }
  1371.  
  1372. /*
  1373.  * The user has tried to cut, copy or paste into the lookup dialog.
  1374.  * We'll try to handle that here.
  1375.  */
  1376. handleLookupDialogEdit()
  1377. {
  1378. }
  1379.  
  1380.     
  1381. /*
  1382.  * Process mouse clicks in menu bar
  1383.  */
  1384. void doCommand(mResult)
  1385.     long    mResult;
  1386.     {
  1387.     int                 theMenu, theItem;
  1388.     char                daName[256];
  1389.     GrafPtr             savePort;
  1390.     extern void            showAboutMeDialog();
  1391.     extern Boolean        gDoneFlag;
  1392.     short                ignore;
  1393.         
  1394.     theItem = LoWord(mResult);
  1395.     theMenu = HiWord(mResult);        /* This is the resource ID */
  1396.  
  1397.     switch (theMenu) {
  1398.         case appleID:
  1399.             if (theItem == aboutMeCommand) 
  1400.                 showAboutMeDialog();
  1401.             else {
  1402.                 GetItem(GetMHandle(appleID), theItem, daName);
  1403.                 GetPort(&savePort);
  1404.                 ignore = OpenDeskAcc(daName);
  1405.                 SetPort(savePort);
  1406.                 }
  1407.             break;
  1408.  
  1409.         case fileID:
  1410.             switch (theItem) {
  1411.                 case lookupCommand:
  1412.                     ShowWindow(gLookupDialog);        /* show lookup prefs window */
  1413.                     SelectWindow(gLookupDialog);
  1414.                     break;
  1415.                 case quitCommand:
  1416.                     gDoneFlag = true;                /* Request exit */
  1417.                     break;
  1418.                 default:
  1419.                     break;
  1420.                 }
  1421.             break;
  1422.  
  1423.         case editID:
  1424.             /*
  1425.              * If this is for a 'standard' edit item,
  1426.              * run it through SystemEdit first.
  1427.              * SystemEdit will return false if it's not a system window.
  1428.              */
  1429.             if ((theItem <= clearCommand) && SystemEdit(theItem-1)) {
  1430.                 break;
  1431.             }
  1432.             
  1433.             /*
  1434.              * Otherwise, it's my window.
  1435.              * and we don't need the Edit menu so boogie...
  1436.              */
  1437.             if(FrontWindow() == gLookupDialog) {
  1438.                 SysBeep(1);
  1439.             }
  1440.             break;        
  1441.         default:
  1442.             break;
  1443.  
  1444.         } /*endsw theMenu*/
  1445.  
  1446.     HiliteMenu(0);
  1447. } /* doCommand */
  1448.  
  1449.  
  1450.  
  1451. /* 
  1452.  *    handles "OK" button outlining for our About...& Echo dialogs.
  1453.  */
  1454. pascal void aboutDialogOKFrame (WindowPtr theWindow, short itemNo)
  1455. {
  1456.     Rect        r;
  1457.     short        kind;
  1458.     Handle        h;
  1459.     PenState    ps;
  1460.  
  1461.     GetPenState(&ps);
  1462.     GetDItem(theWindow, itemNo, &kind, &h, &r);
  1463.     PenSize(3, 3);
  1464.     FrameRoundRect(&r, 16, 16);
  1465.     SetPenState(&ps);
  1466. }
  1467.  
  1468.  
  1469. /* 
  1470.  *    these few lines center the about box to the main screen 1/6 of the way from the bottom of the 
  1471.  *    menubar to the bottom of the main screen.  so decreeth the great John S. 
  1472.  *    noticed the skilled non-use of "with" 
  1473.  */
  1474. void centerDialog(WindowPtr theWindow)
  1475. {
  1476.     short        h, v;
  1477.  
  1478.     #ifdef THINK_C
  1479.         h = (screenBits.bounds.right - screenBits.bounds.left) / 2 - (theWindow->portRect.right - theWindow->portRect.left) / 2;
  1480.         v = (screenBits.bounds.bottom - screenBits.bounds.top) - (theWindow->portRect.bottom - theWindow->portRect.top) - GetMBarHeight();
  1481.     #else
  1482.         h = (qd.screenBits.bounds.right - qd.screenBits.bounds.left) / 2 - (theWindow->portRect.right - theWindow->portRect.left) / 2;
  1483.         v = (qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - (theWindow->portRect.bottom - theWindow->portRect.top) - GetMBarHeight();
  1484.     #endif
  1485.         v = (v / 3) + GetMBarHeight();
  1486.         
  1487.     /* 
  1488.      *    move the window to the right spot & display it & wait around 
  1489.      */
  1490.     MoveWindow(theWindow, h, v, true);
  1491. }
  1492.  
  1493. /*
  1494.  *     Display the About... dialog.
  1495.  *     Then wait until the OK button is clicked before returning.
  1496.  */
  1497. void showAboutMeDialog()
  1498. {
  1499.     GrafPtr     savePort;
  1500.     DialogPtr    aboutDialog;
  1501.     short        itemType;
  1502.     Handle        itemHdl;
  1503.     Rect        itemRect;
  1504.     short        itemHit = 0;
  1505.     
  1506.     GetPort(&savePort);
  1507.     aboutDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) -1);
  1508.     
  1509.     /* 
  1510.      *    set up the userItem proc for the "OK" button outline 
  1511.      */
  1512.     GetDItem(aboutDialog, 7, &itemType, &itemHdl, &itemRect);
  1513.     SetDItem(aboutDialog, 7, userItem, (Handle) aboutDialogOKFrame, &itemRect);
  1514.  
  1515.     centerDialog((WindowPtr) aboutDialog);
  1516.     
  1517.     ShowWindow(aboutDialog);
  1518.     
  1519. #ifdef THINK_C
  1520.     while(itemHit != OK) 
  1521.         ModalDialog(0L, &itemHit);
  1522. #else
  1523.     while(itemHit != ok) 
  1524.         ModalDialog(0L, &itemHit);
  1525. #endif
  1526.  
  1527.     DisposDialog(aboutDialog);
  1528.  
  1529.     SetPort(savePort);
  1530. } /* showAboutMeDialog */
  1531.  
  1532. /*
  1533.  *     Alert user to problem, then exit to shell
  1534.  */
  1535.  
  1536.